#include "tcpclient.h"
#include "ui_tcpclient.h"
#include<QDebug>
#include <QHostAddress>
#include<QMessageBox>
#include"groupchat.h"
#include<QDir>
#include <QRegularExpression>
#include"tipwidget.h"
#include"messageboxwidget.h"
TcpClient::TcpClient(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::TcpClient)
{
    ui->setupUi(this);
    setWindowIcon(QIcon(":/img/application.png"));

    //去窗口边框
    setWindowFlags(Qt::FramelessWindowHint | windowFlags());
    //把窗口背景设置为透明;
    setAttribute(Qt::WA_TranslucentBackground);

    qDebug()<<"主线程："<<QThread::currentThread();
    m_workerThread = new QThread;
    m_worker = new SocketWorker;
    m_worker->moveToThread(m_workerThread);
    m_workerThread->start();

    //与服务器连接
    connect(this, &TcpClient::connectToServer, m_worker, &SocketWorker::connectToServer);
    loadConfig();

    connect(m_worker,&SocketWorker::sendTipMessage,this,&TcpClient::showTipMessage);

    //1.注册
    connect(this,&TcpClient::registerSignal,m_worker,&SocketWorker::usrRegister);
    //2.登录
    connect(this,&TcpClient::logInSignal,m_worker,&SocketWorker::usrLogIn);
    //3.
    connect(this,&TcpClient::searchUsrByNameSignal,m_worker,&SocketWorker::searchUsrByName);
    //4.
    connect(this,&TcpClient::addUsrSignal,m_worker,&SocketWorker::addUsr);
    //5.
    connect(this,&TcpClient::flushFriendListSignal,m_worker,&SocketWorker::flushFriendList);
    //6.
    connect(this,&TcpClient::deleteFriendSignal,m_worker,&SocketWorker::deleteFriend);

    //7.
    connect(this,&TcpClient::sendGroupChatSignal,m_worker,&SocketWorker::groupChatRquset);

    //8.
    connect(this,&TcpClient::sendPrivateChatSignal,m_worker,&SocketWorker::privateChatRequest);

    //9.
    connect(this,&TcpClient::offlineSignal,m_worker,&SocketWorker::usrOffline);

    //10.
    connect(this,&TcpClient::createNewDirSignal,m_worker,&SocketWorker::createNewDir);

    //11.
    connect(this,&TcpClient::flushDirSignal,m_worker,&SocketWorker::flushCurrentDir);

    //12.
    connect(this,&TcpClient::deleteDir_FileSignal,m_worker,&SocketWorker::deleteDirFile);

    //13.
    connect(this,&TcpClient::renameDir_FileSignal,m_worker,&SocketWorker::renameDirFile);

    //14.
    connect(this,&TcpClient::entryDirSignal,m_worker,&SocketWorker::entryRequest);

    //15.
    connect(this,&TcpClient::backDirSignal,m_worker,&SocketWorker::backDirRequest);

    //16.
    connect(this,&TcpClient::uploadFileSignal,m_worker,&SocketWorker::uploadFileRequest);

    //17.
    connect(this,&TcpClient::downLoadFileSignal,m_worker,&SocketWorker::downloadFileRequest);

    //18.
    connect(this,&TcpClient::moveFileSignal,m_worker,&SocketWorker::moveFileRequest);

    //19.
    connect(this,&TcpClient::logOffSignal,m_worker,&SocketWorker::usrLogOff);

    //20.
    connect(this,&TcpClient::onlineFriSignal,m_worker,&SocketWorker::onlineFriendList);

    //21.
    connect(this,&TcpClient::shareFileSignal,m_worker,&SocketWorker::shareFileToFriend);

    //更新进度条
    connect(m_worker,&SocketWorker::setProgressBarVal,this,&TcpClient::setProgressBarValue);
    connect(m_worker,&SocketWorker::setProgessBarClosedEn,this,&TcpClient::setProgessBarClosedEnabled);
    connect(m_worker,&SocketWorker::hideProgressBar,this,&TcpClient::hideProgressBar);
    connect(m_worker,&SocketWorker::showProgressBar,this,&TcpClient::showProgressBar);
    connect(m_worker,&SocketWorker::setProgressBarTitle,this,&TcpClient::setProgressBarTitle);

    //更新状态栏
    connect(m_worker,&SocketWorker::setStatusBar,this,&TcpClient::setStatusBarMsg);

    connect(m_worker,&SocketWorker::logInSuccessSignal,this,&TcpClient::usrLogInSuccess);

    connect(m_worker,&SocketWorker::flushSearchPage,this,&TcpClient::flushSearchPage);

    //table搜索数据
    connect(m_worker,&SocketWorker::sendSearchData,this,&TcpClient::getSearchData);

    //好友列表刷新
    connect(m_worker,&SocketWorker::updateFriList,this,&TcpClient::updateFriendList);

    //
    connect(m_worker,&SocketWorker::sendPriChatMsg,this,&TcpClient::getPrivateChatMsg);

    //
    connect(m_worker,&SocketWorker::sendGroupChatMsg,this,&TcpClient::getGroupChatMsg);

    connect(m_worker,&SocketWorker::updateFileList,this,&TcpClient::updateFileList);

    //分享文件
    connect(m_worker,&SocketWorker::handleShareFileSignal,this,&TcpClient::handleShareFileRequest);
    connect(this,&TcpClient::shareFileFeedBack,m_worker,&SocketWorker::handleShareFileFeedBack);

    //
    connect(m_worker,&SocketWorker::sendOnlineFriendList,this,&TcpClient::getOnlineFriendList);

    //添加好友
    connect(m_worker,&SocketWorker::addFriendSignal,this,&TcpClient::handleAddFriendRequest);
    connect(this,&TcpClient::addFriendHandle,m_worker,&SocketWorker::handleAddFriendResult);

    connect(this,&TcpClient::modifyInfoSignal,m_worker,&SocketWorker::handleModifyInfo);

    connect(m_worker,&SocketWorker::closeMainWinSignal,this,&TcpClient::closeMainWinow);

}

TcpClient::~TcpClient()
{
    TipWidget::release();
    if(m_worker){
        m_worker->deleteLater();
        m_worker=nullptr;
    }
    if(m_workerThread){
        m_workerThread->quit();
        m_workerThread->wait();
        m_workerThread->deleteLater();
        m_workerThread=nullptr;
    }

    delete ui;
}

//加载配置文件
void TcpClient::loadConfig()
{
    QFile file(":/client.config");
    if(file.open(QIODevice::ReadOnly)){
        QByteArray data=file.readAll();
        QString strData=data.toStdString().c_str();
        strData.replace("\r\n"," ");
        QStringList strList=strData.split(" ");
        QString ip=strList.at(0);
        unsigned short port=strList.at(1).toUShort();
        m_ip=ip;
        m_port=port;
        emit connectToServer(m_ip,m_port);
    }else{
        TipWidget::getInstance()->showTip("打开配置文件失败！", TipWidget::Error, 1500, this);
    }

    file.close();
}


//返回单例
TcpClient &TcpClient::getInstance()
{
    //不管调用多少次getInstance()返回的都是instance
    static TcpClient instance;
    return instance;
}

//1.注册
void TcpClient::on_regBtn_clicked()
{
    QString name=ui->usrLineEdit->text();
    QString password=ui->pwdLineEdit->text();
    if(!validateString(name)){
        QMessageBox::critical(this,"critical","用户名只能由英文大小写字母以及数字和下划线组成，且最大长度为31！");
        return;
    }
    if(!validateString(password)){
        QMessageBox::critical(this,"critical","密码只能由英文大小写字母以及数字和下划线组成，且最大长度为31");
        return;
    }
    if((!name.trimmed().isEmpty())&&(!password.trimmed().isEmpty())){
        emit registerSignal(name.trimmed(),password.trimmed());
    }else{
        QMessageBox::critical(this,"critical","注册失败，用户名或密码为空");     //注册失败，直接在前端这里判
    }

    ui->usrLineEdit->clear();
    ui->pwdLineEdit->clear();
}

//2.登录
void TcpClient::on_logInBtn_clicked()
{
    QString name=ui->usrLineEdit->text();
    QString password=ui->pwdLineEdit->text();
    //账号密码初步校验
    if((!name.trimmed().isEmpty())&&(!password.trimmed().isEmpty())){
        emit logInSignal(name.trimmed(),password.trimmed());

    }else{
        QMessageBox::critical(this,"critical","登录失败，用户名或密码为空");     //登录失败，直接在前端这里判
    }

    ui->usrLineEdit->clear();
    ui->pwdLineEdit->clear();
}


//3.根据名称查找用户
void TcpClient::searchUsr(QString name)
{
    emit searchUsrByNameSignal(name);
}

//4.添加好友
void TcpClient::addUsr(QString addName)
{
    //addName 为被添加用户
    emit addUsrSignal(addName);
}

//5.刷新好友列表
void TcpClient::flushFriendList()
{
    emit flushFriendListSignal();
}

//6.删除好友
void TcpClient::deleteFriend(QString deleteName)
{
    emit deleteFriendSignal(deleteName);

}

//7.群聊
void TcpClient::groupChat(QString msg)
{
    emit sendGroupChatSignal(msg);
}

//8.私聊好友
void TcpClient::privateChat(QString chatName,QString msg)
{
    emit sendPrivateChatSignal(chatName,msg);
}

//9.用户下线
void TcpClient::usrOffline()
{
    emit offlineSignal();
}

//10.新建文件夹
void TcpClient::createDir(QString createDirName)
{
    emit createNewDirSignal(createDirName);
}

//11.刷新文件夹
void TcpClient::flushDir()
{
    emit flushDirSignal();
}

//12.删除文件/文件夹
void TcpClient::delDir_File(QString dir_FileName)
{
    emit deleteDir_FileSignal(dir_FileName);
}

//13.重命名文件/文件夹
void TcpClient::renameDir_File(QString oldName,QString newName)
{
    emit renameDir_FileSignal(oldName,newName);
}

//14.进入文件夹
void TcpClient::entryDir(QString dirName)
{
    emit entryDirSignal(dirName);
}

//15.返回上一级
void TcpClient::backDir()
{
    emit backDirSignal();

}

//16.上传文件
void TcpClient::uploadFile(QString upLoadFilePath)
{
    emit uploadFileSignal(upLoadFilePath);
}

//17.下载文件
void TcpClient::downLoadFile(QString fileName,QString saveFilePath)
{
    emit downLoadFileSignal(fileName,saveFilePath);
}

//18.移动文件操作
void TcpClient::moveFile(QString sourcePath,QString fileName,QString targetPath)
{
    emit moveFileSignal(sourcePath,fileName,targetPath);
}



//20.获取在线好友
void TcpClient::getOnlineFriend()
{
    emit onlineFriSignal();
}

//21.分享文件
void TcpClient::shareFile(QList<QString> friendList,QString fileName)
{
    emit shareFileSignal(friendList,fileName);
}

//19.注销账号
void TcpClient::usrLogOff()
{
    emit logOffSignal();
    setProgressBarTitle("注销账号");
    showProgressBar();
}

//修改用户信息
void TcpClient::modifyUsrInfo(QString oldUsrName,QString newUsrName,QString newPwd)
{
    emit modifyInfoSignal(oldUsrName,newUsrName,newPwd);
    setProgressBarTitle("修改用户信息");
    showProgressBar();
}

void TcpClient::closeMainWinow()
{
    setProgressBarValue(100);
    setProgessBarClosedEnabled(true);
    hideProgressBar();
    m_mainwindow->hide();
    this->show();

    if(m_mainwindow){
        delete m_mainwindow;
        m_mainwindow=nullptr;
    }
}

//校验
bool TcpClient::validateString(const QString &input) {
    QRegularExpression regex("^[A-Za-z0-9_]{1,31}$");
    QRegularExpressionMatch match = regex.match(input);
    if (!match.hasMatch()) {
        return false;
    }
    return true;
}

QString TcpClient::curDirPath()
{
    return m_worker->curDirPath();
}

QString TcpClient::usrName()
{
    return m_worker->usrName();
}

QString TcpClient::usrPassword(){
    return m_worker->password();
}

void TcpClient::showTipMessage(int flag,QString parent,const QString&txt,int duration)           //显示不同类型的弹窗
{
    //flag=1:information
    //flag=2:warning
    //flag=3:critical

    if(flag==1){
        if(parent=="mainWindow"){
            TipWidget::getInstance()->showTip(txt, TipWidget::Info, duration, m_mainwindow);
        }else if(parent=="tcpClient"){
            TipWidget::getInstance()->showTip(txt, TipWidget::Info, duration, this);
        }
    }else if(flag==2){
        if(parent=="mainWindow"){
            TipWidget::getInstance()->showTip(txt, TipWidget::Warning, duration, m_mainwindow);
        }else if(parent=="tcpClient"){
            TipWidget::getInstance()->showTip(txt, TipWidget::Warning, duration, this);
        }
    }else if(flag==3){
        if(parent=="mainWindow"){
            TipWidget::getInstance()->showTip(txt, TipWidget::Error, duration, m_mainwindow);
        }else if(parent=="tcpClient"){
            TipWidget::getInstance()->showTip(txt, TipWidget::Error, duration, this);
        }
    }

}

void TcpClient::setProgressBarValue(int value)
{
    m_mainwindow->setProgressValue(value);
}

void TcpClient::setProgessBarClosedEnabled(bool flag)
{
    m_mainwindow->setCloseEnabled(flag);
}

void TcpClient::hideProgressBar()
{
    m_mainwindow->hideProgressBar();
}

void TcpClient::showProgressBar()
{
    m_mainwindow->showProgressBar();
}

void TcpClient::setProgressBarTitle(const QString &title)
{
    m_mainwindow->setProgressBarTip(title);
}

void TcpClient::setStatusBarMsg(const QString &msg)
{
    m_mainwindow->setStatusBarMsg(msg);
}

void TcpClient::usrLogInSuccess(QString name)
{
    //隐藏登录界面
    this->hide();
    //创建m_mainwindow
    if(!m_mainwindow){
        m_mainwindow=new MainWindow;
        connect(m_mainwindow,&MainWindow::backToLogIn,this,[=](){
            m_mainwindow->hide();
            this->show();
            usrOffline();

            if(m_mainwindow){
                delete m_mainwindow;
                m_mainwindow=nullptr;
            }
        });
        //显示主界面
        m_mainwindow->show();
        m_mainwindow->setTitle(name);
        m_mainwindow->logInSet();
    }
}

//刷新搜索页
void TcpClient::flushSearchPage()
{
    m_mainwindow->getFriend()->flushSearchPage();
}

void TcpClient::getSearchData(QList<UserInfo> resultList)
{
    m_mainwindow->getFriend()->getFriendSearchData(resultList);
}

void TcpClient::getOnlineFriendList(QList<QString> resultList)
{
    m_mainwindow->getFileSystem()->onlineFriendList(resultList);
}

void TcpClient::handleShareFileRequest(const QString &usrName, const QString &filePath)
{
    // qDebug()<<"用户："+usrName+" 向您分享了文件："+filePath;
    //同意接收分享文件
    MessageBoxWidget *widget=new MessageBoxWidget;
    widget->setMessageBox(QString("%1 向您分享文件： %2  是否接收？").arg(usrName).arg(filePath),
                          MessageBoxWidget::Info
                          ,m_mainwindow);
    connect(widget,&MessageBoxWidget::confirmSignal,this,[=](){
        emit shareFileFeedBack(true,filePath);
    });
    connect(widget,&MessageBoxWidget::cancelSignal,this,[=](){
        emit shareFileFeedBack(false,filePath);
    });
    widget->show();
}

void TcpClient::updateFriendList(QMap<QString, QString> friendList)
{
    m_mainwindow->getFriend()->updateFriendList(friendList);
}

void TcpClient::getPrivateChatMsg(const QString &chatName, const QString &msg)
{
    //获取私聊消息
    m_mainwindow->getFriend()->recvPrivateChat(chatName,msg);
}

void TcpClient::getGroupChatMsg(const QString &msg,const QString&timeText)
{
    if(groupChat::getInstance()->isHidden()){
        groupChat::getInstance()->show();
    }
    groupChat::getInstance()->updateGroupShowMsg(msg,timeText);
}

void TcpClient::updateFileList(QMap<QString, int> fileList)
{
    m_mainwindow->getFileSystem()->updateFileList(fileList);
}

void TcpClient::handleAddFriendRequest(const QString&addName, const QString&usrName)
{
    MessageBoxWidget *widget=new MessageBoxWidget;
    widget->setMessageBox(QString("%1 想加您为好友").arg(usrName),MessageBoxWidget::Info,m_mainwindow);
    connect(widget,&MessageBoxWidget::confirmSignal,this,[=](){     //同意添加好友
        emit addFriendHandle(true,addName,usrName);
    });
    connect(widget,&MessageBoxWidget::cancelSignal,this,[=](){     //不同意添加好友
        emit addFriendHandle(false,addName,usrName);
    });
    widget->show();
}


void TcpClient::on_miniumBtn_clicked()
{
    showMinimized();
}


void TcpClient::on_closeBtn_clicked()
{
    close();
}

